package com.swak.benchmark;

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.springframework.beans.BeanUtils;

import com.swak.bean.BeanA;
import com.swak.bean.BeanB;
import com.swak.utils.bean.BeanCopier;
import com.swak.utils.bean.BeanCopiers;

/**
 * 每次修改都需要install
 * 
 * Benchmark                                 Mode  Cnt         Score   Error  Units
 * CopyProperty.BeanCopiers_copyProperties  thrpt       25834510.802          ops/s
 * CopyProperty.BeanUtils_copyProperties    thrpt        1133335.382          ops/s
 * CopyProperty.native_copyProperties       thrpt       27090318.509          ops/s
 * 
 * @author lifeng
 */
@Warmup(iterations = 1) // 预热的迭代次数
@OutputTimeUnit(TimeUnit.SECONDS)
@Measurement(iterations = 1, time = -1, timeUnit = TimeUnit.SECONDS, batchSize = -1)
@Threads(4)
@Fork(1)
public class CopyProperty {

	@State(Scope.Benchmark)
	public static class BenchmarkState {
		BeanCopier<BeanA, BeanB> copier = BeanCopiers.create(BeanA.class, BeanB.class);
	}

	@Benchmark
	public void BeanUtils_copyProperties(BenchmarkState state) {
		BeanA a = new BeanA();
		BeanB b = new BeanB();
		BeanUtils.copyProperties(a, b);
	}

	@Benchmark
	public void BeanCopiers_copyProperties(BenchmarkState state) {
		BeanA a = new BeanA();
		state.copier.transform(a);
	}

	@Benchmark
	public void native_copyProperties(BenchmarkState state) {
		BeanA beanA = new BeanA();
		BeanB beanB = new BeanB();
		beanB.setAsset(beanA.getAsset());
		beanB.setId(beanA.getId());
		beanB.setBirthday(beanA.getBirthday());
		beanB.setAge(beanA.getAge());
		beanB.setName(beanA.getName());
		beanB.setSize(beanA.getSize());
	}

	public static void main(String[] args) throws RunnerException {
		Options opt = new OptionsBuilder().include(CopyProperty.class.getSimpleName()).forks(1).build();
		new Runner(opt).run();
	}
}
